/***************************************************
> Copyright (C) 2024 ==KINGYI== All rights reserved.
> File Name: server.c
> Author:cjy
> Mail: 
> Created Time: 2024年08月17日 星期六 17时03分16秒
***************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cJSON.h"
#include <sys/epoll.h>

#define MAX_EVENTS 10

struct data
{
	int type;
	char count[10];
	float num1;
	float num2;
};

struct number
{
	float sum;
};


int main(int argc,const char* argv[])
{
	int sock = 0;
	int listen_sock = 0;
	int ret = 0;
	char buf[1024] = {0};
	char *dest;

	struct sockaddr_in addr;
    	memset(&addr,0,sizeof(addr));

	sock = socket(AF_INET,SOCK_STREAM,0);
	if(sock == -1){
		perror("sock");
		exit(-1);
	}

	addr.sin_family = AF_INET;
        addr.sin_port = htons(6661);
        addr.sin_addr.s_addr = inet_addr("192.168.198.128");

	ret = bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr));
	if(ret == -1)
	{
		perror("bind");
		exit(-1);
	}
	
	listen(sock, 5);
	// 定义事件结构体和数组
   	struct epoll_event ev;
    	struct epoll_event events[MAX_EVENTS];

	// 定义监听套接字、连接套接字、文件描述符数量、epoll 文件描述符
    	int conn_sock, nfds, epollfd;

	 // 创建 epoll 实例
	epollfd = epoll_create1(0);

	if (epollfd == -1) {
		perror("epoll_create1");
        	exit(EXIT_FAILURE);
    	}
	
	
	// 初始化 epoll 事件结构体
    	ev.events = EPOLLIN; // 设置读就绪事件
    	ev.data.fd = sock;   // 关联监听套接字
    
    	// 将监听套接字添加到 epoll 中进行监控
    	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
        	perror("epoll_ctl: listen_sock");
        	exit(EXIT_FAILURE);
    	}
	
	while(1) {
		nfds = epoll_wait(epollfd,events,MAX_EVENTS,-1);
		if (nfds == -1){
			perror("epoll_wait");
			exit(EXIT_FAILURE);
		}
		
		for (int n = 0; n < nfds; n++) {
			if(events[n].data.fd == sock) {
				conn_sock = accept(sock,NULL,NULL);
				if (conn_sock == -1) {
					perror("accept");
					exit(EXIT_FAILURE);
				}
				ev.events = EPOLLIN;
				
				ev.data.fd = sock;
				if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
        				perror("epoll_ctl: listen_sock");
        				exit(EXIT_FAILURE);
    				} else {
                			ret = recv(events[n].data.fd, buf, sizeof(buf), 0);
                			if (ret == -1) {
                    				perror("recv");
                    				exit(-1);
                			}
				puts(buf);

        cJSON *json = NULL;
        struct data dat;
        memset(&dat, 0, sizeof(dat));

        struct number num;
        memset(&num, 0, sizeof(num));

        json = cJSON_Parse(buf);

        cJSON *node = NULL;

        node = cJSON_GetObjectItem(json, "type");
        if (node == NULL) {
            printf("can't find type\n");
            exit(-1);
        }
        if (node->type == cJSON_Number) {
            dat.type = node->valueint;
        }

        node = cJSON_GetObjectItem(json, "count");
        if (node == NULL) {
            printf("can't find count\n");
            exit(-1);
        }
        if (node->type == cJSON_String) {
            strcpy(dat.count, node->valuestring);
        }

        node = cJSON_GetObjectItem(json, "num1");
        if (node == NULL) {
            printf("can't find num1\n");
            exit(-1);
        }
        if (node->type == cJSON_Number) {
            dat.num1 = node->valuedouble;
        }

        node = cJSON_GetObjectItem(json, "num2");
        if (node == NULL) {
            printf("can't find num2\n");
            exit(-1);
        }
        if (node->type == cJSON_Number) {
            dat.num2 = node->valuedouble;
        }

        if (dat.type == 1) {
            num.sum = dat.num1 + dat.num2;
            printf("%f\n", num.sum);
        } else if (dat.type == 2) {
            num.sum = dat.num1 - dat.num2;
            printf("%f\n", num.sum);
        } else if (dat.type == 3) {
            num.sum = dat.num1 * dat.num2;
            printf("%f\n", num.sum);
        } else if (dat.type == 4) {
            num.sum = dat.num1 / dat.num2;
            printf("%f\n", num.sum);
        }

        json = cJSON_CreateObject();
        cJSON_AddItemToObject(json, "sum", cJSON_CreateNumber(num.sum));

        dest = cJSON_Print(json);

        ret = send(events[n].data.fd, dest, sizeof(dest), 0);
        if (ret == -1) {
            perror("send");
            exit(-1);
        }
        cJSON_Delete(json);
    }

}
		}


		}
    return 0;
}












